As Antonia and I continue to explore toxic facilities within Oxnard and Malibu we have shifted our methods and goals. Initially inspired by UCLA's Toxic Tides project and focus on enviromental justice, we are now taking a closer look at the EPA's TRI (toxic release inventory) that gives us data on sites of toxic releases within Calfornia. For the purpose of our research we are taking a closer look at Oxnard (a predominantely Latinx community) and the greater Los Angeles area.
Not only does the TRI site give us meaningful data, it also gives us insight and reseach into the impacts of toxic releases. A "release" is a an exposure of a chemical means that it is emitted to the air or water, or placed in some type of land disposal. TRI tracks the management of certain toxic chemicals that may pose a threat to human health and the environment. U.S. facilities in different industry sectors must report annually how much of each chemical is released to the environment. In general, chemicals covered by the TRI Program are those that may cause Cancer or other chronic human health effects, significant adverse acute human health effects and significant adverse environmental effects.
Antonia and I are beginning to see what these trends look like on a smaller spatial scale, looking at individual cities and attempting to use an enviromental justice framework that observes the communities being diproportionately affected.
Does the socio-economic demographics of an area correlate with the disproportionate distribution of toxic facility waste, especially in identified disadvantaged communities, that are environmental injustice concerns?
#general data wrangling tasks
import pandas as pd
#read and visualize spatial data
import geopandas as gpd
#providing basemaps
import contextily as ctx
#give power to plots
import matplotlib.pyplot as plt
# for interactive plots
import plotly.express as px
/opt/conda/lib/python3.9/site-packages/geopandas/_compat.py:106: UserWarning: The Shapely GEOS version (3.9.1-CAPI-1.14.2) is incompatible with the GEOS version PyGEOS was compiled with (3.10.1-CAPI-1.16.0). Conversions between both will be slow. warnings.warn(
#name dataset as pd and read/show dataset
dfox=pd.read_csv('updatedoxnard_trisummary2020 - Sheet1-5.csv')
# convert df to gdf
gdfox = gpd.GeoDataFrame(dfox, crs='epsg:4326', geometry=gpd.points_from_xy(dfox.Longitude, dfox.Latitude))
#geometry put the longitude and latitide points together in new column as object types
gdfox
| Longitude | Latitude | Name | Address | Industry Sector | Releases (lb) | Releases (lb) Mean | geometry | |
|---|---|---|---|---|---|---|---|---|
| 0 | -119.183020 | 34.140350 | New-Indy Oxnard LLC | 5936 Perkins Road, Oxnard, CA 93033 | Paper | 10,001-100,000 | 55000.5 | POINT (-119.18302 34.14035) |
| 1 | -119.168445 | 34.141707 | Aluminum Precision Products INC | 1001 MC Wane Bouvelard, Oxnard, CA 93033 | Fabricated Metals | 101-10,000 | 5050.5 | POINT (-119.16845 34.14171) |
| 2 | -119.168110 | 34.196130 | Cemex Oxnard Plant | 548 Diaz Avenue, Oxnard, CA 93030 | Nonmetallic Mineral Product | 0.00 | 0.0 | POINT (-119.16811 34.19613) |
| 3 | -119.147180 | 34.198100 | Parker Hannifin Corp | 2340 Eastman Ave, Oxnard, CA 93030 | Machinery | 10,001-100,000 | 55000.5 | POINT (-119.14718 34.19810) |
| 4 | -119.130352 | 34.205928 | PTI Technologies Inc | 501 N Del Norte Boulevard, Oxnard, CA 93030 | Transportation Equipment | 101-10,000 | 5050.5 | POINT (-119.13035 34.20593) |
| 5 | -119.140427 | 34.209468 | The Procter & Gamble Paper Product CO | 800 N Rice Avenue, Oxnard, CA 93030 | Paper | 101-10,000 | 5050.5 | POINT (-119.14043 34.20947) |
| 6 | -119.163291 | 34.249140 | Southern Counties Oil CO LP DBA SC Fuels | 3815 East Vineyard Avenue, Oxnard, CA 93036 | Petroleum Bulk Terminals | 101-10,000 | 5050.5 | POINT (-119.16329 34.24914) |
| 7 | -119.129346 | 34.199354 | Associated Ready Mixed Concrete Inc | 392 S. Del Norte Boulevard, Oxnard, CA 93030 | Nonmetallic Mineral Product | 0.00 | 0.0 | POINT (-119.12935 34.19935) |
| 8 | -119.143053 | 34.270536 | Vulcan Materials-Saticoy | 6029 Vineyard Avenue, Oxnard, CA 93030 | Petroleum | >0-100 | 50.0 | POINT (-119.14305 34.27054) |
gdfox.plot(figsize=(30, 20))
plt.ylabel('Latitude')
plt.xlabel('Longitude')
plt.title('Plot of Oxnard, CA TRI Facilities in 2020')
Text(0.5, 1.0, 'Plot of Oxnard, CA TRI Facilities in 2020')
ox_toxic = gpd.read_file("oxnard_toxic.csv")
#using a shortened data set that inccludes just Oxnard locations we upload our data of Oxnard toxic releases.
ox_toxic['Latitude'] = ox_toxic['Latitude'].astype(float)
ox_toxic['Longitude'] = ox_toxic['Longitude'].astype(float)
facility_by_sector_type_ox = ox_toxic['Industry Sector'].value_counts().reset_index()
facility_by_sector_type_ox
#We begin to produce a bar graph by calling the industry sector column and the counts of each type
| index | Industry Sector | |
|---|---|---|
| 0 | Paper | 2 |
| 1 | Nonmetallic Mineral Product | 2 |
| 2 | Fabricated Metals | 1 |
| 3 | Machinery | 1 |
| 4 | Transportation Equipment | 1 |
| 5 | Petroleum Bulk Terminals | 1 |
| 6 | Petroleum | 1 |
facility_by_sector_type_ox.columns=['industry_sector','count']
facility_by_sector_type_ox
| industry_sector | count | |
|---|---|---|
| 0 | Paper | 2 |
| 1 | Nonmetallic Mineral Product | 2 |
| 2 | Fabricated Metals | 1 |
| 3 | Machinery | 1 |
| 4 | Transportation Equipment | 1 |
| 5 | Petroleum Bulk Terminals | 1 |
| 6 | Petroleum | 1 |
fig = px.bar(facility_by_sector_type_ox.head(20),
x='industry_sector',
y='count',
title='Oxnard Toxic Releases by Industry Sector',
labels={
'industry_sector':'Industry Sector',
'count':'Count'
})
fig.show()
newdata=dfox.drop(['Longitude','Latitude', 'Address', 'Industry Sector', 'Releases (lb)', 'geometry'], axis = 1)
#name new dataframe with name as index and not as"0,1,2.."
dfoxx=newdata.set_index("Name")
dfoxx
#Releases (lb) Mean labels
#10,001-100,000lb=55,000.5lb
#101-10,000lb=5,050.5lb
#>0-100lb=50lb
#0lb=0lb
| Releases (lb) Mean | |
|---|---|
| Name | |
| New-Indy Oxnard LLC | 55000.5 |
| Aluminum Precision Products INC | 5050.5 |
| Cemex Oxnard Plant | 0.0 |
| Parker Hannifin Corp | 55000.5 |
| PTI Technologies Inc | 5050.5 |
| The Procter & Gamble Paper Product CO | 5050.5 |
| Southern Counties Oil CO LP DBA SC Fuels | 5050.5 |
| Associated Ready Mixed Concrete Inc | 0.0 |
| Vulcan Materials-Saticoy | 50.0 |
#querying data
#newdata=dfoxx.loc[['Name'], ['Releases(lb)']]
#plot dataframe with edits as bar graph
#dfoxx['Releases (lb) Mean']=dfoxx['Releases (lb) Mean'].astype(float)
dfoxx.plot(figsize=(10, 6), kind='bar')
#customize graph features to add x and y labels, title, and position graph legend
plt.ylabel('Number of Waste Releases in pounds')
plt.xlabel('Name of Facilities')
plt.title('The Amount of Toxic Waste per TRI Facility')
plt.legend(loc='upper right')
#display customized graph
plt.show()
#this bar graph shows that surveyed White people own more units than surveyed Black and Asian people
ox_toxic.info
<bound method DataFrame.info of Longitude Latitude Name \
0 -119.183020 34.140350 New-Indy Oxnard LLC
1 -119.168445 34.141707 Aluminum Precision Products INC
2 -119.168110 34.196130 Cemex Oxnard Plant
3 -119.147180 34.198100 Parker Hannifin Corp
4 -119.130352 34.205928 PTI Technologies Inc
5 -119.140427 34.209468 The Procter & Gamble Paper Product CO
6 -119.163291 34.249140 Southern Counties Oil CO LP DBA SC Fuels
7 -119.129346 34.199354 Associated Ready Mixed Concrete Inc
8 -119.143053 34.270536 Vulcan Materials-Saticoy
Address Industry Sector \
0 5936 Perkins Road, Oxnard, CA 93033 Paper
1 1001 MC Wane Bouvelard, Oxnard, CA 93033 Fabricated Metals
2 548 Diaz Avenue, Oxnard, CA 93030 Nonmetallic Mineral Product
3 2340 Eastman Ave, Oxnard, CA 93030 Machinery
4 501 N Del Norte Boulevard, Oxnard, CA 93030 Transportation Equipment
5 800 N Rice Avenue, Oxnard, CA 93030 Paper
6 3815 East Vineyard Avenue, Oxnard, CA 93036 Petroleum Bulk Terminals
7 392 S. Del Norte Boulevard, Oxnard, CA 93030 Nonmetallic Mineral Product
8 6029 Vineyard Avenue, Oxnard, CA 93030 Petroleum
geometry
0 None
1 None
2 None
3 None
4 None
5 None
6 None
7 None
8 None >
fig = px.scatter_mapbox(ox_toxic,
lat='Latitude',
lon='Longitude',
mapbox_style="stamen-terrain")
fig.show()
fig = px.scatter_mapbox(ox_toxic,
lat='Latitude',
lon='Longitude',
color="Industry Sector",
labels={'Industry Sector':'Industry Sector'},
mapbox_style="stamen-terrain"
)
fig.show()
The map help us visualize the location and spread/clustering of toxic releases and the bar graph lets us take a closer look at the most prominent types of toxic industry in this city.
la_toxic = gpd.read_file("toxic_la_data.csv",GEOM_POSSIBLE_NAMES="geometry", KEEP_GEOM_COLUMNS="NO")
Here something was off with my csv file and I had to look up what code could fix a "recursion," error
la_toxic.shape
(110, 10)
la_toxic['Latitude'] = la_toxic['Latitude'].astype(float)
la_toxic['Longitude'] = la_toxic['Longitude'].astype(float)
#we transform our latititudes and longitudes into floats
# show me distinct value of charges
facility_by_sector_type = la_toxic.industry_sector.value_counts().reset_index()
facility_by_sector_type
| index | industry_sector | |
|---|---|---|
| 0 | Fabricated Metals | 47 |
| 1 | Chemicals | 25 |
| 2 | Nonmetallic Mineral Product | 16 |
| 3 | Food | 5 |
| 4 | Primary Metals | 4 |
| 5 | Hazardous Waste | 3 |
| 6 | Textiles | 2 |
| 7 | Miscellaneous Manufacturing | 2 |
| 8 | Chemical Wholesalers | 2 |
| 9 | Paper | 2 |
| 10 | Petroleum Bulk Terminals | 1 |
| 11 | Plastics and Rubber | 1 |
# rename the columns
facility_by_sector_type.columns=['industry_sector','count']
facility_by_sector_type
| industry_sector | count | |
|---|---|---|
| 0 | Fabricated Metals | 47 |
| 1 | Chemicals | 25 |
| 2 | Nonmetallic Mineral Product | 16 |
| 3 | Food | 5 |
| 4 | Primary Metals | 4 |
| 5 | Hazardous Waste | 3 |
| 6 | Textiles | 2 |
| 7 | Miscellaneous Manufacturing | 2 |
| 8 | Chemical Wholesalers | 2 |
| 9 | Paper | 2 |
| 10 | Petroleum Bulk Terminals | 1 |
| 11 | Plastics and Rubber | 1 |
fig = px.bar(facility_by_sector_type.head(20),
x='industry_sector',
y='count',
title='Los Angeles Toxic Releases by Industry Sector',
labels={
'industry_sector':'Industry Sector',
'count':'Count'
})
fig.show()
fig = px.scatter_mapbox(la_toxic,
lat='Latitude',
lon='Longitude',
color="industry_sector",
labels={'industry_sector':'Industry Sector'},
mapbox_style="stamen-terrain"
)
fig.show()
#using a shortened data set that inccludes just Los Angeles locations we upload our data of Oxnard toxic releases.
#I had to manually add Industry sector types onto the excel sheet because the downloaded file did not include it
The map of toxic releases in Los Angeles helps us see where most of the industry clusters, we can see that there is a lot more toxic releases in East LA than West LA. The bar graph allows us to further examine the most prominent types of industry sectors and toxic releases.
#loading geojson file
gdfox=gpd.read_file('oxnardcensus.geojson')
#plot data
gdfox.plot(figsize=(12,12))
<AxesSubplot:>
# columns to keep
columns_to_keep = ['geoid',
'name',
'B03002001',
'B03002002',
'B03002003',
'B03002004',
'B03002005',
'B03002006',
'B03002007',
'B03002008',
'B03002009',
'B03002012',
'geometry']
# redefine gdf with only columns to keep
gdfox = gdfox[columns_to_keep]
#rename column headers with race
gdfox.columns = ['geoid',
'name',
'Total',
'Non Hispanic',
'Non Hispanic White',
'Non Hispanic Black',
'Non Hispanic American Indian and Alaska Native',
'Non Hispanic Asian',
'Non Hispanic Native Hawaiian and Other Pacific Islander',
'Non Hispanic Some other race',
'Non Hispanic Two or more races',
'Hispanic',
'geometry']
gdfox
| geoid | name | Total | Non Hispanic | Non Hispanic White | Non Hispanic Black | Non Hispanic American Indian and Alaska Native | Non Hispanic Asian | Non Hispanic Native Hawaiian and Other Pacific Islander | Non Hispanic Some other race | Non Hispanic Two or more races | Hispanic | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 14000US06111002500 | Census Tract 25, Ventura, CA | 5374.0 | 4419.0 | 4014.0 | 44.0 | 97.0 | 142.0 | 0.0 | 0.0 | 122.0 | 955.0 | MULTIPOLYGON (((-119.28488 34.27208, -119.2847... |
| 1 | 14000US06111002901 | Census Tract 29.01, Ventura, CA | 5665.0 | 2747.0 | 1538.0 | 196.0 | 0.0 | 679.0 | 9.0 | 0.0 | 325.0 | 2918.0 | MULTIPOLYGON (((-119.22113 34.22552, -119.2210... |
| 2 | 14000US06111002905 | Census Tract 29.05, Ventura, CA | 5433.0 | 2339.0 | 1110.0 | 450.0 | 0.0 | 587.0 | 0.0 | 10.0 | 182.0 | 3094.0 | MULTIPOLYGON (((-119.26689 34.23456, -119.2654... |
| 3 | 14000US06111003010 | Census Tract 30.10, Ventura, CA | 3226.0 | 805.0 | 445.0 | 82.0 | 1.0 | 255.0 | 4.0 | 0.0 | 18.0 | 2421.0 | MULTIPOLYGON (((-119.18629 34.22030, -119.1862... |
| 4 | 14000US06111003011 | Census Tract 30.11, Ventura, CA | 5539.0 | 1004.0 | 612.0 | 65.0 | 0.0 | 260.0 | 9.0 | 0.0 | 58.0 | 4535.0 | MULTIPOLYGON (((-119.19458 34.22066, -119.1945... |
| 5 | 14000US06111003012 | Census Tract 30.12, Ventura, CA | 675.0 | 13.0 | 13.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 662.0 | MULTIPOLYGON (((-119.19133 34.24133, -119.1907... |
| 6 | 14000US06111003013 | Census Tract 30.13, Ventura, CA | 5509.0 | 1934.0 | 1188.0 | 230.0 | 0.0 | 310.0 | 10.0 | 24.0 | 172.0 | 3575.0 | MULTIPOLYGON (((-119.19446 34.22956, -119.1944... |
| 7 | 14000US06111003100 | Census Tract 31, Ventura, CA | 14299.0 | 5059.0 | 2093.0 | 319.0 | 94.0 | 2278.0 | 92.0 | 0.0 | 183.0 | 9240.0 | MULTIPOLYGON (((-119.17739 34.22648, -119.1771... |
| 8 | 14000US06111003201 | Census Tract 32.01, Ventura, CA | 4230.0 | 103.0 | 32.0 | 7.0 | 22.0 | 15.0 | 0.0 | 0.0 | 27.0 | 4127.0 | MULTIPOLYGON (((-119.17733 34.20163, -119.1773... |
| 9 | 14000US06111003300 | Census Tract 33, Ventura, CA | 8956.0 | 1942.0 | 1523.0 | 88.0 | 19.0 | 121.0 | 0.0 | 0.0 | 191.0 | 7014.0 | MULTIPOLYGON (((-119.19467 34.20925, -119.1946... |
| 10 | 14000US06111003605 | Census Tract 36.05, Ventura, CA | 9631.0 | 4653.0 | 2765.0 | 445.0 | 0.0 | 891.0 | 31.0 | 60.0 | 461.0 | 4978.0 | MULTIPOLYGON (((-119.22134 34.18140, -119.2213... |
| 11 | 14000US06111003608 | Census Tract 36.08, Ventura, CA | 4024.0 | 1366.0 | 771.0 | 68.0 | 10.0 | 270.0 | 28.0 | 62.0 | 157.0 | 2658.0 | MULTIPOLYGON (((-119.20799 34.19046, -119.2079... |
| 12 | 14000US06111003609 | Census Tract 36.09, Ventura, CA | 5863.0 | 5347.0 | 5112.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 119.0 | 516.0 | MULTIPOLYGON (((-119.24867 34.19740, -119.2477... |
| 13 | 14000US06111003612 | Census Tract 36.12, Ventura, CA | 4962.0 | 4040.0 | 3701.0 | 75.0 | 83.0 | 64.0 | 0.0 | 0.0 | 117.0 | 922.0 | MULTIPOLYGON (((-119.23645 34.17589, -119.2356... |
| 14 | 14000US06111003700 | Census Tract 37, Ventura, CA | 6687.0 | 724.0 | 228.0 | 410.0 | 0.0 | 86.0 | 0.0 | 0.0 | 0.0 | 5963.0 | MULTIPOLYGON (((-119.19503 34.17741, -119.1950... |
| 15 | 14000US06111003801 | Census Tract 38.01, Ventura, CA | 5033.0 | 348.0 | 107.0 | 35.0 | 0.0 | 206.0 | 0.0 | 0.0 | 0.0 | 4685.0 | MULTIPOLYGON (((-119.18953 34.18811, -119.1895... |
| 16 | 14000US06111003802 | Census Tract 38.02, Ventura, CA | 2849.0 | 258.0 | 106.0 | 107.0 | 0.0 | 45.0 | 0.0 | 0.0 | 0.0 | 2591.0 | MULTIPOLYGON (((-119.18668 34.18190, -119.1865... |
| 17 | 14000US06111003900 | Census Tract 39, Ventura, CA | 6984.0 | 872.0 | 241.0 | 216.0 | 0.0 | 387.0 | 0.0 | 0.0 | 28.0 | 6112.0 | MULTIPOLYGON (((-119.17755 34.17352, -119.1775... |
| 18 | 14000US06111004000 | Census Tract 40, Ventura, CA | 7179.0 | 816.0 | 365.0 | 108.0 | 0.0 | 298.0 | 0.0 | 0.0 | 45.0 | 6363.0 | MULTIPOLYGON (((-119.17766 34.16246, -119.1776... |
| 19 | 14000US06111004101 | Census Tract 41.01, Ventura, CA | 6947.0 | 1041.0 | 543.0 | 216.0 | 10.0 | 186.0 | 0.0 | 0.0 | 86.0 | 5906.0 | MULTIPOLYGON (((-119.18618 34.17556, -119.1854... |
| 20 | 14000US06111004304 | Census Tract 43.04, Ventura, CA | 5978.0 | 2594.0 | 1754.0 | 433.0 | 16.0 | 190.0 | 66.0 | 0.0 | 135.0 | 3384.0 | MULTIPOLYGON (((-119.22142 34.17600, -119.2213... |
| 21 | 14000US06111004503 | Census Tract 45.03, Ventura, CA | 5112.0 | 1409.0 | 558.0 | 146.0 | 0.0 | 615.0 | 0.0 | 0.0 | 90.0 | 3703.0 | MULTIPOLYGON (((-119.17782 34.14751, -119.1778... |
| 22 | 14000US06111004504 | Census Tract 45.04, Ventura, CA | 5777.0 | 910.0 | 207.0 | 119.0 | 12.0 | 539.0 | 0.0 | 0.0 | 33.0 | 4867.0 | MULTIPOLYGON (((-119.17777 34.15551, -119.1777... |
| 23 | 14000US06111004505 | Census Tract 45.05, Ventura, CA | 2208.0 | 206.0 | 144.0 | 32.0 | 0.0 | 13.0 | 11.0 | 6.0 | 0.0 | 2002.0 | MULTIPOLYGON (((-119.18649 34.15483, -119.1864... |
| 24 | 14000US06111004506 | Census Tract 45.06, Ventura, CA | 7788.0 | 605.0 | 263.0 | 150.0 | 19.0 | 127.0 | 0.0 | 0.0 | 46.0 | 7183.0 | MULTIPOLYGON (((-119.18656 34.14939, -119.1865... |
| 25 | 14000US06111004600 | Census Tract 46, Ventura, CA | 2035.0 | 1753.0 | 1295.0 | 134.0 | 28.0 | 117.0 | 19.0 | 0.0 | 160.0 | 282.0 | MULTIPOLYGON (((-119.16128 34.11793, -119.1602... |
| 26 | 14000US06111004704 | Census Tract 47.04, Ventura, CA | 1372.0 | 391.0 | 232.0 | 48.0 | 0.0 | 30.0 | 10.0 | 20.0 | 51.0 | 981.0 | MULTIPOLYGON (((-119.14392 34.16554, -119.1434... |
| 27 | 14000US06111004710 | Census Tract 47.10, Ventura, CA | 5707.0 | 1488.0 | 539.0 | 187.0 | 0.0 | 453.0 | 178.0 | 7.0 | 124.0 | 4219.0 | MULTIPOLYGON (((-119.16629 34.15484, -119.1662... |
| 28 | 14000US06111004711 | Census Tract 47.11, Ventura, CA | 3552.0 | 1475.0 | 172.0 | 20.0 | 0.0 | 1148.0 | 96.0 | 20.0 | 19.0 | 2077.0 | MULTIPOLYGON (((-119.16853 34.17336, -119.1682... |
| 29 | 14000US06111004715 | Census Tract 47.15, Ventura, CA | 5417.0 | 1231.0 | 491.0 | 144.0 | 8.0 | 489.0 | 0.0 | 33.0 | 66.0 | 4186.0 | MULTIPOLYGON (((-119.18892 34.13864, -119.1886... |
| 30 | 14000US06111004716 | Census Tract 47.16, Ventura, CA | 5066.0 | 790.0 | 255.0 | 34.0 | 0.0 | 478.0 | 6.0 | 0.0 | 17.0 | 4276.0 | MULTIPOLYGON (((-119.16005 34.18335, -119.1600... |
| 31 | 14000US06111004717 | Census Tract 47.17, Ventura, CA | 3951.0 | 476.0 | 142.0 | 105.0 | 0.0 | 163.0 | 0.0 | 0.0 | 66.0 | 3475.0 | MULTIPOLYGON (((-119.15715 34.17315, -119.1568... |
| 32 | 14000US06111004901 | Census Tract 49.01, Ventura, CA | 7229.0 | 3039.0 | 1128.0 | 385.0 | 0.0 | 1214.0 | 19.0 | 35.0 | 258.0 | 4190.0 | MULTIPOLYGON (((-119.15973 34.20893, -119.1597... |
| 33 | 14000US06111004902 | Census Tract 49.02, Ventura, CA | 5072.0 | 106.0 | 94.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 4966.0 | MULTIPOLYGON (((-119.15976 34.19728, -119.1597... |
| 34 | 14000US06111005002 | Census Tract 50.02, Ventura, CA | 3339.0 | 209.0 | 187.0 | 21.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 3130.0 | MULTIPOLYGON (((-119.15876 34.22519, -119.1587... |
| 35 | 14000US06111005003 | Census Tract 50.03, Ventura, CA | 7261.0 | 1317.0 | 975.0 | 143.0 | 0.0 | 88.0 | 22.0 | 79.0 | 10.0 | 5944.0 | MULTIPOLYGON (((-119.17310 34.23200, -119.1729... |
| 36 | 14000US06111005004 | Census Tract 50.04, Ventura, CA | 9833.0 | 4698.0 | 2716.0 | 285.0 | 36.0 | 1081.0 | 84.0 | 0.0 | 496.0 | 5135.0 | MULTIPOLYGON (((-119.18952 34.24251, -119.1875... |
| 37 | 14000US06111008600 | Census Tract 86, Ventura, CA | 7920.0 | 1517.0 | 598.0 | 100.0 | 11.0 | 594.0 | 0.0 | 0.0 | 214.0 | 6403.0 | MULTIPOLYGON (((-119.19485 34.19013, -119.1948... |
| 38 | 14000US06111008700 | Census Tract 87, Ventura, CA | 6029.0 | 1387.0 | 1073.0 | 65.0 | 27.0 | 202.0 | 0.0 | 0.0 | 20.0 | 4642.0 | MULTIPOLYGON (((-119.19468 34.20143, -119.1946... |
| 39 | 14000US06111008800 | Census Tract 88, Ventura, CA | 5582.0 | 1533.0 | 913.0 | 37.0 | 9.0 | 404.0 | 0.0 | 0.0 | 170.0 | 4049.0 | MULTIPOLYGON (((-119.20829 34.18135, -119.2082... |
| 40 | 14000US06111008900 | Census Tract 89, Ventura, CA | 3385.0 | 489.0 | 372.0 | 20.0 | 0.0 | 80.0 | 0.0 | 0.0 | 17.0 | 2896.0 | MULTIPOLYGON (((-119.19502 34.17186, -119.1950... |
| 41 | 14000US06111009100 | Census Tract 91, Ventura, CA | 4870.0 | 253.0 | 68.0 | 82.0 | 0.0 | 50.0 | 11.0 | 0.0 | 42.0 | 4617.0 | MULTIPOLYGON (((-119.17745 34.19018, -119.1774... |
| 42 | 14000US06111990100 | Census Tract 9901, Ventura, CA | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | MULTIPOLYGON (((-119.48652 34.00000, -119.4680... |
#add percent columns for each race
gdfox['Percent Non Hispanic White'] = gdfox['Non Hispanic White']/gdfox['Total']*100
gdfox['Percent Non Hispanic Black'] = gdfox['Non Hispanic Black']/gdfox['Total']*100
gdfox['Percent Non Hispanic American Indian and Alaska Native'] = gdfox['Non Hispanic American Indian and Alaska Native']/gdfox['Total']*100
gdfox['Percent Non Hispanic Asian'] = gdfox['Non Hispanic Asian']/gdfox['Total']*100
gdfox['Percent Non Hispanic Native Hawaiian and Other Pacific Islander'] = gdfox['Non Hispanic Native Hawaiian and Other Pacific Islander']/gdfox['Total']*100
gdfox['Percent Non Hispanic Some other race'] = gdfox['Non Hispanic Some other race']/gdfox['Total']*100
gdfox['Percent Non Hispanic Two or more races'] = gdfox['Non Hispanic Two or more races']/gdfox['Total']*100
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1322: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
#Found census tract that Parker Hannifan Facility is in
#Census Tracts:
#STATE CODE: 06
#GEOID: 06111004902
#CENTLAT: +34.2084355
#COUNTY CODE: 111
#AREAWATER: 0
#NAME: Census Tract 49.02
#CENTLON: -119.1342637
#TRACT CODE: 004902
#AREALAND: 10177889
#source: https://geocoding.geo.census.gov/geocoder/geographies/address?street=2340+Eastman+Ave&city=Oxnard&state=CA&zip=93030&benchmark=4&vintage=4
#locking census tract 49.02/geoid 06111004902 on index 33 in onxard census data table
parker=gdfox.query('index==33')
parker
| geoid | name | Total | Non Hispanic | Non Hispanic White | Non Hispanic Black | Non Hispanic American Indian and Alaska Native | Non Hispanic Asian | Non Hispanic Native Hawaiian and Other Pacific Islander | Non Hispanic Some other race | Non Hispanic Two or more races | Hispanic | geometry | Percent Non Hispanic White | Percent Non Hispanic Black | Percent Non Hispanic American Indian and Alaska Native | Percent Non Hispanic Asian | Percent Non Hispanic Native Hawaiian and Other Pacific Islander | Percent Non Hispanic Some other race | Percent Non Hispanic Two or more races | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 33 | 14000US06111004902 | Census Tract 49.02, Ventura, CA | 5072.0 | 106.0 | 94.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 4966.0 | MULTIPOLYGON (((-119.15976 34.19728, -119.1597... | 1.853312 | 0.0 | 0.0 | 0.236593 | 0.0 | 0.0 | 0.0 |
#plot data
parker.plot(figsize=(12,12))
<AxesSubplot:>
# for network analysis
import networkx as nx
# for street network analysis
import osmnx as ox
# for basemaps
import contextily as ctx
#looking at Oxnard city and driving distance between toxic facilties and nearest residential areas
address = '2340, Eastman Avenue, Oxnard, Ventura County, California, 93030, United States'
network_type = 'drive'
trip_times = [5, 10, 15, 20] #in minutes
meters_per_minute = 1609 # googled avergae mph per minute and converted to meters
%%time
# see how long it takes this cell to run
# download the street network
G = ox.graph_from_address(address, network_type=network_type, dist = 2000)
CPU times: user 1.24 s, sys: 35.8 ms, total: 1.27 s Wall time: 1.28 s
#what is graph is this?
type(G)
networkx.classes.multidigraph.MultiDiGraph
# plot using oxmnx
fig, ax = ox.plot_graph(G,figsize=(12,12))
#shows grid of oxnard
# project our network data to Web Mercator (measurements are in meters)
G = ox.project_graph(G, to_crs='epsg:3857')
# convert nodes and edges to geodataframes
gdfpa_nodes, gdfpa_edges = ox.graph_to_gdfs(G)
gdfpa_nodes.sample(10)
| y | x | street_count | lon | lat | highway | geometry | |
|---|---|---|---|---|---|---|---|
| osmid | |||||||
| 7432299931 | 4.054560e+06 | -1.326483e+07 | 4 | -119.159970 | 34.191614 | NaN | POINT (-13264827.228 4054560.216) |
| 7432299893 | 4.055005e+06 | -1.326480e+07 | 3 | -119.159722 | 34.194922 | NaN | POINT (-13264799.520 4055005.469) |
| 95522891 | 4.056575e+06 | -1.326529e+07 | 3 | -119.164102 | 34.206586 | NaN | POINT (-13265287.155 4056575.325) |
| 3216703754 | 4.057566e+06 | -1.326557e+07 | 3 | -119.166605 | 34.213946 | NaN | POINT (-13265565.833 4057566.012) |
| 95501809 | 4.057164e+06 | -1.326310e+07 | 4 | -119.144425 | 34.210959 | NaN | POINT (-13263096.722 4057163.963) |
| 95642704 | 4.057153e+06 | -1.326542e+07 | 3 | -119.165324 | 34.210875 | NaN | POINT (-13265423.199 4057152.628) |
| 7180138182 | 4.056327e+06 | -1.326240e+07 | 4 | -119.138184 | 34.204741 | NaN | POINT (-13262402.010 4056327.011) |
| 95505714 | 4.056230e+06 | -1.326410e+07 | 3 | -119.153446 | 34.204019 | NaN | POINT (-13264100.935 4056229.802) |
| 95417231 | 4.053836e+06 | -1.326540e+07 | 3 | -119.165128 | 34.186232 | NaN | POINT (-13265401.369 4053835.930) |
| 6081088976 | 4.056690e+06 | -1.326284e+07 | 3 | -119.142078 | 34.207439 | NaN | POINT (-13262835.455 4056690.170) |
gdfpa_edges.head()
| osmid | name | highway | oneway | length | geometry | lanes | ref | maxspeed | junction | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| u | v | key | ||||||||||
| 95173394 | 95536640 | 0 | [10738055, 10714703] | [Beacon Place, Universe Circle] | residential | False | 548.837 | LINESTRING (-13265403.150 4053573.653, -132653... | NaN | NaN | NaN | NaN |
| 95536637 | 0 | 10739932 | Pacific Avenue | tertiary | False | 187.589 | LINESTRING (-13265403.150 4053573.653, -132654... | NaN | NaN | NaN | NaN | |
| 95631603 | 0 | 10739932 | Pacific Avenue | tertiary | False | 125.875 | LINESTRING (-13265403.150 4053573.653, -132654... | NaN | NaN | NaN | NaN | |
| 95536640 | 95173394 | 0 | [10714703, 10738055] | [Beacon Place, Universe Circle] | residential | False | 548.837 | LINESTRING (-13264958.830 4053343.275, -132649... | NaN | NaN | NaN | NaN |
| 95536641 | 0 | 743170077 | Emerson Avenue | tertiary | False | 101.574 | LINESTRING (-13264958.830 4053343.275, -132649... | NaN | NaN | NaN | NaN |
#query only residential roads
#gdfpa_edges=gdfpa_edges.query('highway==residential')
#gdfpa_edges.loc[gdfpa_edges['highway'] == residential]
#Select rows whose column value contains a string
gdfpa_edges.loc[gdfpa_edges['highway'].str.contains('residential')]
gdfpa_edges.plot(figsize=(10,10))
<AxesSubplot:>
# get the bounding box coordinates
minx, miny, maxx, maxy = gdfpa_nodes.geometry.total_bounds
print(minx)
print(miny)
print(maxx)
print(maxy)
-13265721.190172315 4053149.7311939765 -13260910.874600055 4057948.5014720145
# calculate the centroid
centroid_x = (maxx-minx)/2 + minx
centroid_y = (maxy-miny)/2 + miny
print(centroid_x)
print(centroid_y)
-13263316.032386184 4055549.1163329957
# use osmnx's distance.nearest_nodes command to get the id for the nearest node
center_node = ox.distance.nearest_nodes(G,Y=centroid_y,X=centroid_x)
print('The id for the nearest node is ' + str(center_node))
The id for the nearest node is 95565605
# what is this record?
gdfpa_nodes.loc[[center_node]]
| y | x | street_count | lon | lat | highway | geometry | |
|---|---|---|---|---|---|---|---|
| osmid | |||||||
| 95565605 | 4.055551e+06 | -1.326309e+07 | 3 | -119.144398 | 34.198973 | NaN | POINT (-13263093.716 4055550.633) |
# set up the subplot (single plot = ax)
fig, ax = plt.subplots(figsize=(10,10))
# add the edges to ax
gdfpa_edges.plot(ax=ax,
linewidth=0.5,
edgecolor='gainsboro',
zorder=10)
# add all nodes to ax
gdfpa_nodes.plot(ax=ax,
markersize=2,
zorder=20)
# add the center node in red also to ax
gdfpa_nodes.loc[[center_node]].plot(ax=ax,
color='b',
zorder=30)
# no axis
ax.axis('off')
# add a basemap
ctx.add_basemap(ax,source=ctx.providers.CartoDB.Positron)
# a quick look at the data
gdfpa_edges[['osmid','name','highway','length']].sample(5)
| osmid | name | highway | length | |||
|---|---|---|---|---|---|---|
| u | v | key | ||||
| 95598637 | 95525348 | 0 | [10738115, 10734167] | [Paseo Isla, Paseo Lindo] | residential | 175.641 |
| 95416548 | 95549698 | 0 | [10739137, 10740609] | [Del Rey Place, Festivo Street] | residential | 302.642 |
| 95446801 | 95665374 | 0 | 10741881 | Almanor Street | residential | 75.768 |
| 95527009 | 95505717 | 0 | [10734289, 10743595] | [Santa Lucia Avenue, Kohala Street] | residential | 294.148 |
| 95494360 | 95412874 | 0 | 10737855 | Williams Drive | residential | 137.025 |
# create a new column, calculate the time it takes to travel that edge
gdfpa_edges['drive_time'] = gdfpa_edges['length']/meters_per_minute
gdfpa_edges[['osmid','name','highway','length','drive_time']].sample(10)
| osmid | name | highway | length | drive_time | |||
|---|---|---|---|---|---|---|---|
| u | v | key | |||||
| 95569525 | 2005492989 | 0 | 723726873 | North Lombard Street | residential | 75.825 | 0.047126 |
| 95588539 | 3216703662 | 0 | 315547683 | NaN | residential | 10.085 | 0.006268 |
| 95536637 | 95536639 | 0 | 743170077 | Emerson Avenue | tertiary | 159.435 | 0.099089 |
| 95441061 | 95565605 | 0 | 10739080 | Candelaria Road | residential | 290.774 | 0.180717 |
| 95494363 | 95518771 | 0 | 10742687 | Flora Lane | residential | 36.029 | 0.022392 |
| 95536640 | 95173394 | 0 | [10714703, 10738055] | [Beacon Place, Universe Circle] | residential | 548.837 | 0.341104 |
| 95520009 | 95421425 | 0 | 10733769 | Cordova Street | residential | 311.145 | 0.193378 |
| 95631603 | 95173394 | 0 | 10739932 | Pacific Avenue | tertiary | 125.875 | 0.078232 |
| 3216701738 | 95527252 | 0 | [10734416, 10740587] | [Nina Drive, Olivia Drive] | residential | 278.353 | 0.172998 |
| 95478409 | 95494360 | 0 | 10737855 | Williams Drive | residential | 123.126 | 0.076523 |
# assign a color hex code for each trip time isochrone
iso_colors = ox.plot.get_colors(n=len(trip_times),
cmap='YlOrRd',
start=0,
return_hex=True)
# reverse the sort order so that the darker color matches longer times
trip_times.sort(reverse=True)
# create a list of "zipped" time/colors
time_color = list(zip(trip_times, iso_colors))
time_color
[(20, '#ffffcc'), (15, '#febf5a'), (10, '#f43d25'), (5, '#800026')]
# loop through the list of time/colors
for time,color in list(time_color):
print('The color for '+str(time)+' minutes is ' + color)
The color for 20 minutes is #ffffcc The color for 15 minutes is #febf5a The color for 10 minutes is #f43d25 The color for 5 minutes is #800026
# loop through each trip time and associated color
for time, color in list(time_color):
# for each trip time, create an egograph of nodes that fall within that distance
subgraph = nx.ego_graph(G, center_node, radius=time, distance='time')
print('There are ' + str(len(subgraph.nodes())) + ' nodes within ' + str(time) + ' minutes ')
# for each of those nodes, update the gdf_nodes dataframe and assign it with its associated distance color
for node in subgraph.nodes():
gdfpa_nodes.loc[node,'time'] = str(time) + ' mins'
gdfpa_nodes.loc[node,'color'] = color
There are 389 nodes within 20 minutes There are 300 nodes within 15 minutes There are 165 nodes within 10 minutes There are 36 nodes within 5 minutes
# spot check
gdfpa_nodes[['highway','time','color']].sample(20)
| highway | time | color | |
|---|---|---|---|
| osmid | |||
| 95524476 | NaN | 15 mins | #febf5a |
| 95499230 | NaN | 15 mins | #febf5a |
| 95485848 | NaN | 15 mins | #febf5a |
| 5279120140 | NaN | 5 mins | #800026 |
| 95656680 | NaN | 20 mins | #ffffcc |
| 95614833 | NaN | 20 mins | #ffffcc |
| 95440966 | NaN | 20 mins | #ffffcc |
| 95536641 | traffic_signals | 10 mins | #f43d25 |
| 95469442 | NaN | 20 mins | #ffffcc |
| 95585754 | NaN | 20 mins | #ffffcc |
| 95644350 | NaN | 15 mins | #febf5a |
| 95463678 | NaN | 15 mins | #febf5a |
| 95575730 | NaN | 20 mins | #ffffcc |
| 95524477 | NaN | 15 mins | #febf5a |
| 95463669 | NaN | 15 mins | #febf5a |
| 95536654 | NaN | 15 mins | #febf5a |
| 7432299926 | NaN | 10 mins | #f43d25 |
| 3216703684 | NaN | 20 mins | #ffffcc |
| 95424397 | NaN | 10 mins | #f43d25 |
| 95441072 | NaN | 5 mins | #800026 |
# the NaN values then need to be populated with a valid color
gdfpa_nodes['color'].fillna('#cccccc', inplace=True)
# another spot check: are all values in the color column populated?
gdfpa_nodes.sample(10)
| y | x | street_count | lon | lat | highway | geometry | time | color | |
|---|---|---|---|---|---|---|---|---|---|
| osmid | |||||||||
| 3216703684 | 4.057249e+06 | -1.326520e+07 | 3 | -119.163338 | 34.211594 | NaN | POINT (-13265202.141 4057249.400) | 20 mins | #ffffcc |
| 95441057 | 4.055905e+06 | -1.326361e+07 | 3 | -119.149055 | 34.201606 | NaN | POINT (-13263612.131 4055905.058) | 5 mins | #800026 |
| 95485851 | 4.056352e+06 | -1.326554e+07 | 3 | -119.166343 | 34.204929 | NaN | POINT (-13265536.600 4056352.275) | 15 mins | #febf5a |
| 95468871 | 4.057824e+06 | -1.326397e+07 | 3 | -119.152246 | 34.215859 | NaN | POINT (-13263967.352 4057823.575) | 20 mins | #ffffcc |
| 374104279 | 4.055254e+06 | -1.326091e+07 | 1 | -119.124789 | 34.196768 | NaN | POINT (-13260910.875 4055253.875) | 5 mins | #800026 |
| 95569525 | 4.057561e+06 | -1.326365e+07 | 3 | -119.149353 | 34.213905 | NaN | POINT (-13263645.293 4057560.587) | 15 mins | #febf5a |
| 95478411 | 4.057453e+06 | -1.326417e+07 | 3 | -119.154107 | 34.213107 | stop | POINT (-13264174.539 4057453.083) | 15 mins | #febf5a |
| 7180138173 | 4.056539e+06 | -1.326410e+07 | 3 | -119.153472 | 34.206313 | NaN | POINT (-13264103.807 4056538.619) | 10 mins | #f43d25 |
| 95557175 | 4.056045e+06 | -1.326542e+07 | 3 | -119.165323 | 34.202647 | NaN | POINT (-13265423.077 4056045.133) | 15 mins | #febf5a |
| 95440966 | 4.057456e+06 | -1.326443e+07 | 3 | -119.156438 | 34.213125 | NaN | POINT (-13264433.970 4057455.560) | 20 mins | #ffffcc |
#map it
gdfpa_nodes.plot(figsize=(10,10),
color=gdfpa_nodes['color'],
markersize=3)
<AxesSubplot:>
# show only the points within 5 minutes
gdfpa_nodes[gdfpa_nodes['time']=='5 mins']
| y | x | street_count | lon | lat | highway | geometry | time | color | |
|---|---|---|---|---|---|---|---|---|---|
| osmid | |||||||||
| 95427040 | 4.054324e+06 | -1.326483e+07 | 5 | -119.159980 | 34.189861 | traffic_signals | POINT (-13264828.252 4054324.354) | 5 mins | #800026 |
| 897648871 | 4.054322e+06 | -1.326481e+07 | 4 | -119.159817 | 34.189846 | traffic_signals | POINT (-13264810.196 4054322.321) | 5 mins | #800026 |
| 95441057 | 4.055905e+06 | -1.326361e+07 | 3 | -119.149055 | 34.201606 | NaN | POINT (-13263612.131 4055905.058) | 5 mins | #800026 |
| 95441061 | 4.055903e+06 | -1.326309e+07 | 3 | -119.144378 | 34.201588 | NaN | POINT (-13263091.468 4055902.582) | 5 mins | #800026 |
| 95569532 | 4.056006e+06 | -1.326360e+07 | 3 | -119.148984 | 34.202357 | NaN | POINT (-13263604.272 4056006.100) | 5 mins | #800026 |
| 95565607 | 4.055555e+06 | -1.326361e+07 | 4 | -119.149077 | 34.199006 | NaN | POINT (-13263614.580 4055555.074) | 5 mins | #800026 |
| 95441072 | 4.055949e+06 | -1.326294e+07 | 2 | -119.143042 | 34.201931 | NaN | POINT (-13262942.767 4055948.708) | 5 mins | #800026 |
| 95565605 | 4.055551e+06 | -1.326309e+07 | 3 | -119.144398 | 34.198973 | NaN | POINT (-13263093.716 4055550.633) | 5 mins | #800026 |
| 4723364108 | 4.055952e+06 | -1.326286e+07 | 4 | -119.142329 | 34.201953 | traffic_signals | POINT (-13262863.352 4055951.723) | 5 mins | #800026 |
| 95441078 | 4.055948e+06 | -1.326261e+07 | 3 | -119.140044 | 34.201925 | NaN | POINT (-13262609.065 4055947.941) | 5 mins | #800026 |
| 4723364109 | 4.055952e+06 | -1.326285e+07 | 4 | -119.142173 | 34.201956 | traffic_signals | POINT (-13262846.030 4055952.113) | 5 mins | #800026 |
| 5279120140 | 4.055938e+06 | -1.326120e+07 | 4 | -119.127406 | 34.201853 | NaN | POINT (-13261202.187 4055938.196) | 5 mins | #800026 |
| 95441090 | 4.055938e+06 | -1.326119e+07 | 4 | -119.127264 | 34.201852 | NaN | POINT (-13261186.368 4055938.102) | 5 mins | #800026 |
| 95505830 | 4.056382e+06 | -1.326117e+07 | 4 | -119.127077 | 34.205146 | NaN | POINT (-13261165.562 4056381.564) | 5 mins | #800026 |
| 95449269 | 4.055264e+06 | -1.326286e+07 | 5 | -119.142311 | 34.196846 | traffic_signals | POINT (-13262861.426 4055264.360) | 5 mins | #800026 |
| 374104337 | 4.055284e+06 | -1.326466e+07 | 3 | -119.158424 | 34.196991 | NaN | POINT (-13264655.039 4055283.862) | 5 mins | #800026 |
| 95449272 | 4.055469e+06 | -1.326285e+07 | 3 | -119.142216 | 34.198364 | NaN | POINT (-13262850.817 4055468.653) | 5 mins | #800026 |
| 1969327128 | 4.055255e+06 | -1.326120e+07 | 4 | -119.127386 | 34.196774 | NaN | POINT (-13261199.971 4055254.629) | 5 mins | #800026 |
| 6413662985 | 4.054305e+06 | -1.326287e+07 | 3 | -119.142402 | 34.189718 | traffic_signals | POINT (-13262871.523 4054305.055) | 5 mins | #800026 |
| 4723364126 | 4.055549e+06 | -1.326287e+07 | 4 | -119.142350 | 34.198960 | NaN | POINT (-13262865.712 4055548.896) | 5 mins | #800026 |
| 7432299924 | 4.055610e+06 | -1.326480e+07 | 3 | -119.159693 | 34.199413 | NaN | POINT (-13264796.348 4055609.826) | 5 mins | #800026 |
| 95505768 | 4.056520e+06 | -1.326359e+07 | 3 | -119.148853 | 34.206174 | NaN | POINT (-13263589.611 4056519.855) | 5 mins | #800026 |
| 95569526 | 4.056376e+06 | -1.326359e+07 | 3 | -119.148848 | 34.205103 | NaN | POINT (-13263589.088 4056375.709) | 5 mins | #800026 |
| 95533861 | 4.056165e+06 | -1.326322e+07 | 3 | -119.145559 | 34.203537 | NaN | POINT (-13263222.958 4056164.925) | 5 mins | #800026 |
| 95531958 | 4.055547e+06 | -1.326398e+07 | 3 | -119.152354 | 34.198946 | NaN | POINT (-13263979.374 4055546.999) | 5 mins | #800026 |
| 95565617 | 4.055472e+06 | -1.326413e+07 | 3 | -119.153748 | 34.198390 | NaN | POINT (-13264134.553 4055472.166) | 5 mins | #800026 |
| 95569527 | 4.056142e+06 | -1.326359e+07 | 3 | -119.148876 | 34.203363 | NaN | POINT (-13263592.205 4056141.505) | 5 mins | #800026 |
| 95562620 | 4.056154e+06 | -1.326284e+07 | 3 | -119.142136 | 34.203455 | NaN | POINT (-13262841.923 4056153.929) | 5 mins | #800026 |
| 897648486 | 4.055338e+06 | -1.326362e+07 | 1 | -119.149086 | 34.197394 | NaN | POINT (-13263615.582 4055338.155) | 5 mins | #800026 |
| 7432299908 | 4.055461e+06 | -1.326480e+07 | 4 | -119.159710 | 34.198308 | traffic_signals | POINT (-13264798.251 4055461.156) | 5 mins | #800026 |
| 95565624 | 4.055462e+06 | -1.326482e+07 | 3 | -119.159863 | 34.198316 | traffic_signals | POINT (-13264815.306 4055462.179) | 5 mins | #800026 |
| 2196325751 | 4.055291e+06 | -1.326482e+07 | 4 | -119.159880 | 34.197046 | traffic_signals | POINT (-13264817.198 4055291.291) | 5 mins | #800026 |
| 374104279 | 4.055254e+06 | -1.326091e+07 | 1 | -119.124789 | 34.196768 | NaN | POINT (-13260910.875 4055253.875) | 5 mins | #800026 |
| 7432299900 | 4.055292e+06 | -1.326480e+07 | 4 | -119.159725 | 34.197048 | traffic_signals | POINT (-13264799.932 4055291.587) | 5 mins | #800026 |
| 7432299886 | 4.054561e+06 | -1.326481e+07 | 3 | -119.159843 | 34.191621 | NaN | POINT (-13264813.057 4054561.158) | 5 mins | #800026 |
| 6413662989 | 4.053971e+06 | -1.326287e+07 | 2 | -119.142422 | 34.187234 | NaN | POINT (-13262873.738 4053970.785) | 5 mins | #800026 |
# put it in a variable
gdfpa_5 = gdfpa_nodes[gdfpa_nodes['time']=='5 mins']
# plot it
gdfpa_5.plot(figsize=(10,10),color=gdfpa_5.color)
<AxesSubplot:>
# dissolve the nodes by time
isochrones = gdfpa_nodes.dissolve("time")
isochrones
| geometry | y | x | street_count | lon | lat | highway | color | |
|---|---|---|---|---|---|---|---|---|
| time | ||||||||
| 10 mins | MULTIPOINT (-13265544.983 4055762.738, -132654... | 4.053574e+06 | -1.326540e+07 | 3 | -119.165144 | 34.184283 | traffic_signals | #f43d25 |
| 15 mins | MULTIPOINT (-13265721.190 4053727.870, -132656... | 4.056739e+06 | -1.326507e+07 | 4 | -119.162163 | 34.207801 | stop | #febf5a |
| 20 mins | MULTIPOINT (-13265715.402 4056995.566, -132655... | 4.056685e+06 | -1.326483e+07 | 3 | -119.160021 | 34.207401 | stop | #ffffcc |
| 5 mins | MULTIPOINT (-13264828.252 4054324.354, -132648... | 4.054324e+06 | -1.326483e+07 | 5 | -119.159980 | 34.189861 | traffic_signals | #800026 |
# for each row, create a convex hull
isochrones = isochrones.convex_hull.reset_index()
isochrones
| time | 0 | |
|---|---|---|
| 0 | 10 mins | POLYGON ((-13265246.413 4053149.731, -13265404... |
| 1 | 15 mins | POLYGON ((-13263979.819 4053165.650, -13265721... |
| 2 | 20 mins | POLYGON ((-13265267.151 4056468.827, -13265535... |
| 3 | 5 mins | POLYGON ((-13262873.738 4053970.785, -13264828... |
# geometry header has been automatically named "0"
# let's rename that
isochrones.columns=['time','geometry']
isochrones.head()
| time | geometry | |
|---|---|---|
| 0 | 10 mins | POLYGON ((-13265246.413 4053149.731, -13265404... |
| 1 | 15 mins | POLYGON ((-13263979.819 4053165.650, -13265721... |
| 2 | 20 mins | POLYGON ((-13265267.151 4056468.827, -13265535... |
| 3 | 5 mins | POLYGON ((-13262873.738 4053970.785, -13264828... |
isochrones.plot(figsize=(10,10),alpha=0.2,cmap='plasma')
<AxesSubplot:>
# set up the subplots
fig, ax = plt.subplots(figsize=(10,15))
# add the isochrones
isochrones.plot(alpha=0.4,
ax=ax,
column='time',
cmap='plasma',
legend=True,
zorder=20)
# add the center node in red
gdfpa_nodes.loc[[center_node]].plot(ax=ax,color='b', zorder=30)
# add all nodes
gdfpa_nodes.plot(ax=ax,
markersize=1,
zorder=10)
# add the edges
gdfpa_edges.plot(ax=ax,
linewidth=0.5,
alpha=0.2,
zorder=10)
# hide the axis
ax.axis('off')
# give it a title
ax.set_title('Driving areas from center of Parker Hannifan Corp Facility')
# add the basemap
ctx.add_basemap(ax,source=ctx.providers.CartoDB.Positron)
#mapped parker hannifan and nodes and edges within driving distance
As we look at next steps we are looking to continue mapping the proximty from the most polluting facilties to residential areas in Oxnard.
Data research and sourcing by Antonia Izuogu and Lupe Velez. Introduction, Interactive Maps and Sectory Type bar graphs by Lupe Velez Weight Bar Graphs, Isochrone Map and Next Steps by Antonia Izuogu